package com.kaolafm.kradio.k_navi_map.basemvp;

import android.app.Service;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
import android.support.v4.app.Fragment;
import android.support.v4.app.SupportActivity;
import android.view.View;

/**
 * MVP模式Presenter基类,如果使用EventBus，只需要将{@link #useEventBus()}返回true就行了
 * 泛型第一个是继承IModel的M接口(用于处理数据相关的逻辑), 第二个是继承IView的V接口(用于展示)
 * 通过重写{@link #createModel()}方法提供Model
 * @author donald
 * @date 2018/4/13
 */
public abstract class BasePresenter<M extends IModel, V extends IView> implements IPresenter, LifecycleObserver {

    protected M mModel;

    protected V mView;

    public BasePresenter(V view) {
        mView = view;
        mModel = createModel();
    }

    private BasePresenter() {
    }


    @Override
    public void start() {
        //将 LifecycleObserver 注册给 LifecycleOwner 后 @OnLifecycleEvent 才可以正常使用
        if (mView != null && mView instanceof LifecycleOwner) {
            ((LifecycleOwner) mView).getLifecycle().addObserver(this);
            if (mModel != null && mModel instanceof LifecycleObserver) {
                ((LifecycleOwner) mView).getLifecycle().addObserver((LifecycleObserver) mModel);
            }
        }

    }

    /**
     * 创建model类
     * @return
     */
    protected M createModel(){
        return null;
    }

    @Override
    public void destroy() {
        if (mModel != null){
            mModel.destroy();
        }
        mModel = null;
        mView = null;
    }
    /**
     * 只有当 {@code mView} 不为 null, 并且 {@code mView} 实现了 {@link LifecycleOwner} 时, 此方法才会被调用
     * 所以当您想在 {@link Service} 以及一些自定义 {@link View} 或自定义类中使用 {@code Presenter} 时
     * 您也将不能继续使用 {@link OnLifecycleEvent} 绑定生命周期
     *
     * @param owner link {@link SupportActivity} and {@link Fragment}
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestroy(LifecycleOwner owner) {
        /**
         * 注意, 如果在这里调用了 {@link #onDestroy()} 方法, 会出现某些地方引用 {@code mModel} 或 {@code mView} 为 null 的情况
         * 比如在 {@link RxLifecycle} 终止 {@link Observable} 时, 在 {@link io.reactivex.Observable#doFinally(Action)} 中却引用了 {@code mView} 做一些释放资源的操作, 此时会空指针
         * 或者如果你声明了多个 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 时在其他 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
         * 中引用了 {@code mModel} 或 {@code mRootView} 也可能会出现此情况
         */
        owner.getLifecycle().removeObserver(this);
    }

    /**
     * 是否使用EventBus, 默认false 不使用。
     */
    public boolean useEventBus() {
        return false;
    }


}
